package com.cardone.platform.authority.service;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.UUID;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.cardone.common.dto.PaginationDto;
import com.cardone.context.Attributes;
import com.cardone.context.ContextHolder;
import com.cardone.platform.authority.dao.RoleDao;
import com.cardone.platform.authority.dao.RolePermissionDao;
import com.cardone.platform.authority.dao.RoleUserDao;
import com.cardone.platform.authority.dao.UsGroupRoleDao;
import com.cardone.platform.authority.dto.RoleDto;
import com.google.common.collect.Lists;

/**
 * 角色服务
 *
 * @author yaohaitao
 *
 */
@Getter
@Setter
@Slf4j
@Transactional(readOnly = true)
public class RoleDefaultService implements RoleService {
	@Override
	public int deleteByIds(final RoleDto deleteRole) {
		return this.deleteByIds(deleteRole.getIds());
	}

	@Override
	@Transactional(readOnly = false)
	public int deleteByIds(final String ids) {
		int deleteCount = ContextHolder.getBean(RoleDao.class).deleteByIds(ids);

		deleteCount += ContextHolder.getBean(RolePermissionDao.class).deleteByRoleIds(ids);

		deleteCount += ContextHolder.getBean(RoleUserDao.class).deleteByRoleIds(ids);

		deleteCount += ContextHolder.getBean(UsGroupRoleDao.class).deleteByRoleIds(ids);

		return deleteCount;
	}

	@Override
	public <P> P findByCodeOrId(final Class<P> mappedClass, final RoleDto findRole) {
		return ContextHolder.getBean(RoleDao.class).findByCodeOrId(mappedClass, findRole);
	}

	@Override
	public <P> P findById(final Class<P> mappedClass, final RoleDto findRole) {
		return ContextHolder.getBean(RoleDao.class).findById(mappedClass, findRole);
	}

	@Override
	public <P> List<P> findListByLikeCode(final Class<P> mappedClass, final RoleDto findListRole) {
		return ContextHolder.getBean(RoleDao.class).findListByLikeCode(mappedClass, findListRole);
	}

	@Override
	public <P> List<P> findListByUserId(final Class<P> mappedClass, final String userId) {
		return ContextHolder.getBean(RoleDao.class).findListByUserId(mappedClass, userId);
	}

	@Override
	@Transactional(readOnly = false)
	public int insertByCode(final RoleDto insertRole) {
		return ContextHolder.getBean(RoleDao.class).insertByCode(insertRole);
	}

	@Override
	public <P> PaginationDto<P> paginationByLikeCode(final Class<P> mappedClass, final RoleDto paginationRole) {
		return ContextHolder.getBean(RoleDao.class).paginationByLikeCode(mappedClass, paginationRole);
	}

	@Override
	public Integer readByCodeNqIdForCount(final RoleDto readRole) {
		return ContextHolder.getBean(RoleDao.class).readByCodeNqIdForCount(readRole);
	}

	@Override
	public String readIdByCode(final RoleDto readRole) {
		return ContextHolder.getBean(RoleDao.class).readIdByCode(readRole);
	}

	@Override
	public List<String> readIdListByUserId(final String userId) {
		final List<RoleDto> roleList = ContextHolder.getBean(RoleService.class).findListByUserId(RoleDto.class, userId);

		final List<String> idList = Lists.newArrayList();

		if (CollectionUtils.isEmpty(roleList)) {
			return idList;
		}

		for (final RoleDto role : roleList) {
			idList.add(role.getId());
		}

		return idList;
	}

	@Override
	@Transactional(readOnly = false)
	public <P> P saveByIdOrCode(final Class<P> mappedClass, final RoleDto saveRole) {
		if (StringUtils.isBlank(saveRole.getCode())) {
			if (StringUtils.isBlank(saveRole.getId())) {
				saveRole.setId(UUID.randomUUID().toString());
			}

			saveRole.setCode(saveRole.getId());
		}

		if (saveRole.getOrderNum() == null) {
			saveRole.setOrderNum(Double.valueOf(0));
		}

		return ContextHolder.getBean(RoleDao.class).saveByIdOrCode(mappedClass, saveRole);
	}

	@Override
	@Transactional(readOnly = false)
	public <P> P saveForPermissionIds(final Class<P> mappedClass, final RoleDto saveRole) {
		final P p = this.saveByIdOrCode(mappedClass, saveRole);

		String roleId = null;

		try {
			roleId = BeanUtils.getProperty(p, Attributes.id.name());
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			RoleDefaultService.log.error(e.getMessage(), e);
		}

		ContextHolder.getBean(RolePermissionDao.class).saveRoleIdAndPermissionIds(roleId, saveRole.getPermissionIds());

		return p;
	}

	@Override
	@Transactional(readOnly = false)
	public int updateByCode(final RoleDto updateRole) {
		return ContextHolder.getBean(RoleDao.class).updateByCode(updateRole);
	}
}